home *** CD-ROM | disk | FTP | other *** search
- ;;;"defmacex.scm" defmacro:expand* for any Scheme dialect.
- ;;;Copyright 1993-1994 Dorai Sitaram and Aubrey Jaffer.
- ;
- ;Permission to copy this software, to redistribute it, and to use it
- ;for any purpose is granted, subject to the following restrictions and
- ;understandings.
- ;
- ;1. Any copy made of this software must include this copyright notice
- ;in full.
- ;
- ;2. I have made no warrantee or representation that the operation of
- ;this software will be error-free, and I am under no obligation to
- ;provide any services, by way of maintenance, update, or otherwise.
- ;
- ;3. In conjunction with products arising from the use of this
- ;material, there shall be no use of my name in any advertising,
- ;promotional, or sales literature without prior written consent in
- ;each case.
-
- ;;;expand thoroughly, not just topmost expression. While expanding
- ;;;subexpressions, the primitive forms quote, lambda, set!, let/*/rec,
- ;;;cond, case, do, quasiquote: need to be destructured properly. (if,
- ;;;and, or, begin: don't need special treatment.)
-
- (define (defmacro:iqq e depth)
- (letrec
- ((map1 (lambda (f x)
- (if (pair? x) (cons (f (car x)) (map1 f (cdr x)))
- x)))
- (iqq (lambda (e depth)
- (if (pair? e)
- (case (car e)
- ((quasiquote) (list (car e) (iqq (cadr e) (+ 1 depth))))
- ((unquote unquote-splicing)
- (list (car e) (if (= 1 depth)
- (defmacro:expand* (cadr e))
- (iqq (cadr e) (+ -1 depth)))))
- (else (map1 (lambda (e) (iqq e depth)) e)))
- e))))
- (iqq e depth)))
-
- (define (defmacro:expand* e)
- (if (pair? e)
- (let* ((c (macroexpand-1 e)))
- (if (not (eq? e c))
- (defmacro:expand* c)
- (case (car e)
- ((quote) e)
- ((quasiquote) (defmacro:iqq e 0))
- ((lambda define set!)
- (cons (car e) (cons (cadr e) (map defmacro:expand* (cddr e)))))
- ((let)
- (let ((b (cadr e)))
- (if (symbol? b) ;named let
- `(let ,b
- ,(map (lambda (vv)
- `(,(car vv)
- ,(defmacro:expand* (cadr vv))))
- (caddr e))
- ,@(map defmacro:expand*
- (cdddr e)))
- `(let
- ,(map (lambda (vv)
- `(,(car vv)
- ,(defmacro:expand* (cadr vv))))
- b)
- ,@(map defmacro:expand*
- (cddr e))))))
- ((let* letrec)
- `(,(car e) ,(map (lambda (vv)
- `(,(car vv)
- ,(defmacro:expand* (cadr vv))))
- (cadr e))
- ,@(map defmacro:expand* (cddr e))))
- ((cond)
- `(cond
- ,@(map (lambda (c)
- (map defmacro:expand* c))
- (cdr e))))
- ((case)
- `(case ,(defmacro:expand* (cadr e))
- ,@(map (lambda (c)
- `(,(car c)
- ,@(map defmacro:expand* (cdr c))))
- (cddr e))))
- ((do)
- `(do ,(map
- (lambda (initsteps)
- `(,(car initsteps)
- ,@(map defmacro:expand*
- (cdr initsteps))))
- (cadr e))
- ,(map defmacro:expand* (caddr e))
- ,@(map defmacro:expand* (cdddr e))))
- (else (map defmacro:expand* e)))))
- e))
-